package com.errol.generic.baiducloud.basic;

import com.alibaba.fastjson.JSON;
import com.renjia.enums.AccessInterfaceBusinessTypeEnum;
import com.renjia.service.CoreLogIntegrationService;
import com.renjia.service.generic.baiducloud.basic.pojo.BaiduAccessTokenCache;
import com.renjia.service.generic.baiducloud.basic.pojo.BaiduAccessTokenDTO;
import com.renjia.service.generic.http.HttpResult;
import com.renjia.service.generic.http.HttpService;
import com.renjia.service.generic.log.LogService;
import org.springframework.http.HttpMethod;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;

import java.util.HashMap;

/**
 * @author zhang xiao bin
 * @version v1.0
 * @date 2020/09/21
 * @since v4.7.2
 **/
@Service
public class BaiduBasicServiceImpl implements BaiduBasicService {

    private final HashMap<String, BaiduAccessTokenCache> appIdTokenMap = new HashMap<>();
    private final HttpService httpService;
    private final LogService logService;
    private final CoreLogIntegrationService coreLogIntegrationService;
    private static final Object LOCK = new Object();
    // TODO: 2020/9/21 微服务架构使用 redis 缓存

    public BaiduBasicServiceImpl(HttpService httpService, LogService logService, CoreLogIntegrationService coreLogIntegrationService) {
        this.httpService = httpService;
        this.logService = logService;
        this.coreLogIntegrationService = coreLogIntegrationService;
    }

    @Nullable
    @Override
    public String getAccessToken(@NonNull String appId, @NonNull String apiKey, @NonNull String secretKey) {
        if (appIdTokenMap.containsKey(appId) && appIdTokenMap.get(appId).getExpireTimestamp() > System.currentTimeMillis()) {
            return appIdTokenMap.get(appId).getAccessToken();
        }
        synchronized (LOCK) {
            if (appIdTokenMap.containsKey(appId) && appIdTokenMap.get(appId).getExpireTimestamp() > System.currentTimeMillis()) {
                return appIdTokenMap.get(appId).getAccessToken();
            }
            String url = String.format("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s", apiKey, secretKey);
            long t = System.currentTimeMillis();
            HttpResult<BaiduAccessTokenDTO> httpResult = httpService.execute(httpService.builder(url)
                    .usePost()
                    .sendEmptyData()
                    .expectJsonOfClass(BaiduAccessTokenDTO.class)
                    .build());
            if (httpResult.isSuccess()) {
                BaiduAccessTokenDTO dto = httpResult.getData();
                if (dto.getAccessToken() != null && dto.getExpire() != null && dto.getExpire() > 0) {
                    appIdTokenMap.put(appId, new BaiduAccessTokenCache(appId, dto.getAccessToken(), dto.getExpire()));
                    coreLogIntegrationService.generateLog(AccessInterfaceBusinessTypeEnum.BAIDU_PORTRAIT_SEGMENT, "getAccessToken", url, HttpMethod.POST,
                            "", "200", "success", System.currentTimeMillis() - t);
                    return dto.getAccessToken();
                } else {
                    logService.warn("获取百度云 access token 失败：code=" + dto.getErrCode() + "，msg=" + dto.getErrMsg());
                    coreLogIntegrationService.generateLog(AccessInterfaceBusinessTypeEnum.BAIDU_PORTRAIT_SEGMENT, "getAccessToken", url, HttpMethod.POST,
                            "", "200", JSON.toJSONString(dto), System.currentTimeMillis() - t);
                }
            } else {
                coreLogIntegrationService.generateLog(AccessInterfaceBusinessTypeEnum.BAIDU_PORTRAIT_SEGMENT, "getAccessToken", url, HttpMethod.POST,
                        "", String.valueOf(httpResult.getHttpStatus()), httpResult.getException() != null ? httpResult.getException().getMessage() : "", System.currentTimeMillis() - t);
            }
            return null;
        }
    }

    @Override
    public void invalidAccessToken(@NonNull String appId) {
        appIdTokenMap.remove(appId);
    }

}
